#ifndef PUDGE_ENGINE_SIMPLE_HPP
#define PUDGE_ENGINE_SIMPLE_HPP

#include <pudge/grfx/render.hpp>
#include <pudge/grfx/text.hpp>
#include <pudge/ui/sprite.hpp>
#include <pudge/ui/widget.hpp>
#include <pudge/ui/events.hpp>
#include <pudge/ui/canvas.hpp>

namespace pudge { namespace engine {

	struct simple
	{
		/// game context type
		typedef simple game_context_type;

		/// define text and sprite shaders
		typedef pudge::ui::sprite_shader sprite_shader_type;
		typedef pudge::grfx::text_shader text_shader_type;

		/// we need shader_program to point to active shader
		typedef pudge::grfx::shader_program shader_program_type;

		/// events
		typedef pudge::ui::mouse_event mouse_event_type;
		typedef pudge::ui::key_event key_event_type;

		/// event containers
		typedef std::vector<mouse_event_type> mouse_event_list;
		typedef std::vector<key_event_type> key_event_list;

		/// Note the circular type pattern, care should be taken when creating your own contexts
		typedef pudge::ui::widget<simple> widget_type;
		typedef pudge::ui::canvas<simple> canvas_type;

		/// ui frame
		typedef pudge::ui::sprite<float> ui_frame_type;

		struct viewport_type
		{
			int x, y, w, h;
			viewport_type(const int a, const int b, const int c, const int d)
				:	x(a)
				,	y(b)
				,	w(c)
				,	h(d) {}
			viewport_type() : x(0), y(0), w(0), h(0) {}

		} viewport_;

		viewport_type viewport() { return viewport_; }
		void viewport(viewport_type const& v) { viewport_ = v; }

		canvas_type canvas_;
		canvas_type & canvas() { return canvas_; }

		sprite_shader_type sprite_shader_;
		sprite_shader_type & sprite_shader() { return sprite_shader_; }

		text_shader_type text_shader_;
		text_shader_type & text_shader() { return text_shader_; }

		mouse_event_list mouse_events_;
		mouse_event_list & mouse_events() { return mouse_events_; }

		key_event_list key_events_;
		key_event_list & key_events() { return key_events_; }

		shader_program_type * active_shader_;
		shader_program_type * active_shader() { return active_shader_; }
		void active_shader(shader_program_type * s) { active_shader_ = s; }

		simple()
			:	sprite_shader_
			(		"../../../src/shaders/sprite_shader.vert"
			,		"../../../src/shaders/sprite_shader.frag")
			,	text_shader_
			(		"../../../src/shaders/text_shader.vert"
			,		"../../../src/shaders/text_shader.frag" )
			,	active_shader_(NULL) {}
		
		virtual ~simple() {}
	
		void reset()
		{
			mouse_events_.clear();
			key_events_.clear();
			active_shader_ = NULL;
			canvas_.reset();
		}
	};
}}

#endif